package com.season.seasonStudy.javase.j_017_enum0;

/**
 * 在实际编程中，往往存在着这样的“数据集”，它们的数值在程序中是稳定的，
 * 而且“数据集”中的元素是有限的。
 * 
 * 例如星期一到星期日七个数据元素组成了一周的“数据集”，春夏秋冬四个数据元素组成了四季的“数据集”。
 * 
 * 在java中如何更好的使用这些“数据集”呢？
 * 
 * 因此枚举便派上了用场，以下代码详细介绍了枚举的用法。
 * 
 * 类型安全
 * 易于输入
 * 代码清晰
 */

/**
 *  1、想要一个值不可变
 *  final  初始化也可以改变  赋值之后才不可变
 *  枚举  
 *  类型  有限个数  所有值静态常量(默认的)
 *  值固定，不允许改变，调用方便，保证值准确可靠
 *  
 *  2、怎么用
 *  数字（下标） 与枚举值 的 转换
 *  	Grade[] grades =Grade.values();
 *  	Grade g = grades[i];
 *  
 * 		int index = Grade.C.ordinal();
 *  
 *  字符串。。。。。。
 *  	Grade grade = Grade.valueOf("A");
 *  
 *  System.out.println(Grade.valueOf("A").toString());
 *  在枚举的toString重写过了，打印name
 *  
 *  枚举不建议写中文，但是可以写
 */

//枚举类型enum
/*特点：类型限定，值固定静态常量,私有构造方法，
 * 私有属性，公有实例方法和类方法，抽象方法
 * 
 * 数字(下标)与枚举值得转换
 * Grade[] grades=Grade.values();
 * Grade g = grades[0];
 * int index=Grade.C.ordinal();
 * 字符串与枚举值的转换
 * Grade grade = Grade.valueOf("A");
   System.out.println(grade.toString());
*
*	1 请选择宠物种类（1。狗狗 ，2 。企鹅 ，3。猫）：2
*	你选择的是:狗狗
*	宠物自白：
*		
*
*	2 请输入您的宠物类型：dog
*	 您的宠物是：dog
 */


/**
 * 枚举用法详解
 */
public class EnumDemo {
	/**
	 * 普通枚举
	 * 算是一个内部类吧
	 */
	public enum ColorEnum {
		red, green, yellow, blue;
	}

	/**
	 * 枚举像普通的类一样可以添加属性和方法，可以为它添加静态和非静态的属性或方法
	 * 注：枚举写在最前面，否则编译出错
	 */
	public enum SeasonEnum {
		spring, summer, autumn, winter;
		
		private final static String position = "test";
		
		public static SeasonEnum getSeason() {
			if ("test".equals(position))
				return spring;
			else
				return winter;
		}
	}

	/**
	 * 性别<br>
	 * 
	 * 实现带有构造方法的枚举
	 * 通过括号赋值,
	 * 
	 * 而且必须带有一个参构造器和一个属性跟方法，否则编译出错
	 * 
	 * 如果不进行赋值，不能写构造方法
	 * 也不能部分赋值，部分不赋值
	 * 
	 * 构造器默认也只能是private, 从而保证构造函数只能在内部使用
	 */
	public enum Gender {
		MAN("MAN"), WOMEN("WOMEN"), MIDDLE;
		
		private final String value;
		
		Gender() {	//不给值,得给个默认
			this.value = "MIDDLE";
		}

		Gender(String value) {
			this.value = value;
		}
		
		public String getValue() {
			return value;
		}
	}
	
	/**
	 * 订单状态
	 * 实现带有抽象方法的枚举
	 */
	public enum OrderState {
		//public abstract String getName();		不能放在最前面，枚举必须写在最前面

		/** 已取消 */
		CANCEL {
			public String getName() {
				return "已取消";
			}
		},
		/** 待审核 */
		WAITCONFIRM {
			public String getName() {
				return "待审核";
			}
		},
		/** 等待付款 */
		WAITPAYMENT {
			public String getName() {
				return "等待付款";
			}
		},
		/** 正在配货 */
		ADMEASUREPRODUCT {
			public String getName() {
				return "正在配货";
			}
		},
		/** 等待发货 */
		WAITDELIVER {
			public String getName() {
				return "等待发货";
			}
		},
		/** 已发货 */
		DELIVERED {
			public String getName() {
				return "已发货";
			}
		},
		/** 已收货 */
		RECEIVED {
			public String getName() {
				return "已收货";
			}
		};
		public abstract String getName();
	}

	public static void main(String[] args) {
		/** 
		 * 枚举是一种类型，用于定义变量，以限制变量的赋值；
		 * 赋值时通过“枚举名.值”取得枚举中的值
		 * 
		 * enum可以用switch判断
		 */
		ColorEnum colorEnum = ColorEnum.blue;
		switch (colorEnum) {
		case red:
			System.out.println("color is red");
			break;
		case green:
			System.out.println("color is green");
			break;
		case yellow:
			System.out.println("color is yellow");
			break;
		case blue:
			System.out.println("color is blue");
			break;
		}

		// 遍历枚举		enum.values()
		System.out.println("遍历ColorEnum枚举中的值");
		for (ColorEnum color : ColorEnum.values()) {
			System.out.println(color);
		}
		
		// 获取枚举的个数	enum.values().length
		System.out.println("ColorEnum枚举中的值有" + ColorEnum.values().length + "个");

		// 获取枚举的索引位置，默认从0开始	ColorEnum.red.ordinal()
		System.out.println(ColorEnum.red.ordinal());// 0
		System.out.println(ColorEnum.green.ordinal());// 1
		System.out.println(ColorEnum.yellow.ordinal());// 2
		System.out.println(ColorEnum.blue.ordinal());// 3

		// 枚举默认实现了java.lang.Comparable接口
		System.out.println(ColorEnum.red.compareTo(ColorEnum.green));// -1

		// --------------------------
		System.out.println("===========");
		System.err.println("季节为" + SeasonEnum.getSeason());

		// --------------
		System.out.println("===========");
		for (Gender gender : Gender.values()) {
			System.out.println(gender.value);
			System.out.println(gender.getValue());
		}

		// --------------
		System.out.println("===========");
		for (OrderState order : OrderState.values()) {
			//System.out.println(order.getName());
			System.out.println(order.name());
		}
	}

}